/**
* 负责和dbsvr交互的对象
*/

#ifndef __MAINSVR_DB_H__
#define __MAINSVR_DB_H__

#include "maindef.h"

class CMainCtrl;
class CMainDB: public CTEpollObject<CMainDB>
{
protected:
    friend class CMainCtrl;

    /**
    * 连接的状态
    */
    enum
    {
        DB_CLOSED = 0,
        DB_CONNECTING = 1,
        DB_CONNECTED = 2,
    };

    CMainCtrl*      m_pstOwner;
    CTEpoll*        m_pstEpoll;
    CTSocket        m_stSocket;
    int             m_iConnectState;
    CTBuffer        m_stRecvBuffer;
    CTBuffer        m_stSendBuffer;
    int             m_OldConnectFlag;
    int             m_ConnectCountFlag;

public:
    CMainDB() :
        m_stSocket(PF_INET, SOCK_STREAM, false),
        m_iConnectState(DB_CLOSED),
        m_OldConnectFlag(DB_CLOSED),
        m_ConnectCountFlag(0)
    {
    }

    int Init(CMainCtrl& stOwern, CTEpoll& stEpoll);
    void OnDBEvent(CTEpollObject<CMainDB>* pstObject, SOCKET iSocket, int iEvent);

    void CheckConnect();

    /**
    * 发送残留的请求
    */
    void CheckSend();

    int Send(const char* pszBuf, int iBufLen);

protected:
    /**
    * 接收数据, 如果发现是完整的包就让MainCtrl分发处理
    */
    void Recv();

    /**
    * 用于出现收发异常时重新连接
    */
    void ReConnect();

    /**
    * 读取一个Code
    * @param[in] stSocket 要读取的socket
    * @param[in] stBuffer 保存读取的数据
    * @param[out] pszCodeBuf 这个Code在stBuffer的起始位置
    * @param[out] iCodeLen 这个Code的长度, 0表示没有Code没有接收完全 -1表示收到0字节的消息(表示退出)
    * @return 0表示成功 可能还会返回CT_EINPROGRESS CT_EWOULDBLOCK CT_ETIME CT_ECONNRESET
    */
    int RecvOneCode(CTSocket& stSocket,
        CTBuffer& stBuffer,
        char*& pszCodeBuf,
        int& iCodeLen);
};


#endif //__MAINSVR_DB_H__
